﻿using EasyNet.Componets.Core.Serialization;
using EasyNet.Componets.Core.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace EasyNet.Componets.Core
{
    public static class StringExtension
    {
        #region 校验
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        [DebuggerStepThrough, DebuggerHidden]
        public static bool IsNullOrEmpty(this string s)
        {
            return string.IsNullOrEmpty(s);
        }
        /// <summary>
        /// 是否为小数
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsDecimal(this string s)
        {
            string pattern = @"[0].d{1,2}|[1]";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(s);
        }
        /// <summary>
        /// 判断输入的字符串只包含汉字
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsZhChar(this string s)
        {
            string pattern = @"^[\u4e00-\u9fa5]+$";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(s);
        }

        /// <summary>
        /// 判断输入的字符串只包含数字
        /// 可以匹配整数和浮点数
        /// ^-?\d+$|^(-?\d+)(\.\d+)?$
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsNumber(this string input)
        {
            string pattern = "^-?\\d+$|^(-?\\d+)(\\.\\d+)?$";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(input);
        }

        /// <summary>
        /// 判断输入的字符串是否是一个合法的Email地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsEmail(this string input)
        {
            //@"^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$";
            string pattern = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(input);
        }

        /// <summary>
        /// 判断输入的字符串是否是一个超链接
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsURL(this string input)
        {
            string pattern = @"^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(input);
        }

        /// <summary>
        /// 判断输入的字符串是否只包含数字和英文字母
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsLetterOrDigit(this string input)
        {
            string pattern = @"^[A-Za-z0-9]+$";
            Regex regex = new Regex(pattern);
            return regex.IsMatch(input);
        }
        #endregion

        #region 计算字符串的字节长度
        /// <summary>
        /// 计算字符串的字符长度，一个汉字字符将被计算为两个字符
        /// </summary>
        /// <param name="input">需要计算的字符串</param>
        /// <returns>返回字符串的长度</returns>
        public static int GetCount(this string input)
        {
            string pattern = @"[\u4e00-\u9fa5/g]";
            return Regex.Replace(input, pattern, "aa").Length;
        }
        #endregion

        #region 值类型转换
        [DebuggerStepThrough, DebuggerHidden]
        public static int ToInt32(this string s)
        {
            return int.Parse(s);
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static long ToLong(this string s)
        {
            return long.Parse(s);
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static decimal ToDecimal(this string s)
        {
            return decimal.Parse(s);
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static double ToDouble(this string s)
        {
            return double.Parse(s);
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static bool ToBoolean(this string s)
        {
            return bool.Parse(s);
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static int TryToInt32(this string s)
        {
            int v = 0;
            if (!string.IsNullOrEmpty(s))
            {
                int.TryParse(s, out v);
            }
            return v;
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static long TryToLong(this string s)
        {
            long v = 0;
            if (!string.IsNullOrEmpty(s))
            {
                long.TryParse(s, out v);
            }
            return v;
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static decimal TryToDecimal(this string s)
        {
            decimal v = 0;
            if (!string.IsNullOrEmpty(s))
            {
                decimal.TryParse(s, out v);
            }
            return v;
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static double TryToDouble(this string s)
        {
            double v = 0;
            if (!string.IsNullOrEmpty(s))
            {
                double.TryParse(s, out v);
            }
            return v;
        }

        [DebuggerStepThrough, DebuggerHidden]
        public static bool TryToBoolean(this string s)
        {
            bool v = false;
            if (!string.IsNullOrEmpty(s))
            {
                bool.TryParse(s, out v);
            }
            return v;
        }
        #endregion

        #region Base64转换
        /// <summary>
        /// 将Base64编码格式字符串转换成字符串
        /// </summary>
        /// <param name="s"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string ConvertFromBase64(this string s, System.Text.Encoding encoding = null)
        {
            if (encoding == null) encoding = System.Text.Encoding.UTF8;
            var buffer = Convert.FromBase64String(s);
            return encoding.GetString(buffer);
        }

        /// <summary>
        /// 将字符串转换成成Base64编码格式字符串
        /// </summary>
        /// <param name="s"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string ConvertToBase64(this string s, System.Text.Encoding encoding = null)
        {
            if (encoding == null) encoding = System.Text.Encoding.UTF8;
            var buffer = encoding.GetBytes(s);
            return Convert.ToBase64String(buffer);
        }
        #endregion

        #region 反序列化

        /// <summary>
        /// 将 Form表单请求格式字符串转换成数据字典
        /// </summary>
        /// <param name="queryString">表单请求数据</param>
        /// <param name="isKeyLower">字典Key是否转换成小写</param>
        /// <returns>字典</returns>
        public static Dictionary<string, string> ToDictionaryFromFormRequest(this string queryString, bool isKeyLower = false)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            if (queryString.IsNullOrEmpty()) return dic;

            var paramArray = queryString.SplitRemoveEmpty("&");
            foreach (var param in paramArray)
            {
                var arr = param.SplitRemoveEmpty("=");
                if (arr.Length == 0) continue;

                string key = arr[0];
                string value = string.Empty;
                if (arr.Length > 1)
                {
                    value = arr[1];
                }
                if (isKeyLower)
                {
                    key = key.ToLower();
                }
                dic.Add(key, value);
            }
            return dic;
        }

        /// <summary>
        /// 将Json格式字符串反序列化成对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="json">Json格式字符串</param>
        /// <returns>序列化后的对象</returns>
        public static T DeserializeFromJson<T>(this string json) 
        {
            return SerializationUtil.Json.Deserialize<T>(json);
        }

        /// <summary>
        /// 将 Form表单请求格式字符串反序列化成对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="json">Form表单请求格式字符串</param>
        /// <returns>序列化后的对象</returns>
        public static T DeserializeFromFormRequest<T>(this string queryString) where T : new()
        {
            return SerializationUtil.HttpQueryString.Deserialize<T>(queryString);
        }

        /// <summary>
        /// 将Xml格式字符串反序列化成对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="xml">xml格式字符串</param>
        /// <param name="rootNodeName">根节点</param>
        /// <returns>对象</returns>
        public static T DeserializeFromXml<T>(this string xml, string rootNodeName = "xml") where T : new()
        {
            return SerializationUtil.Xml.Deserialize<T>(xml, rootNodeName);
        }
        #endregion
        
        #region 拆分
        /// <summary>
        /// 按字符拆分，移除空字符
        /// </summary>
        /// <param name="data"></param>
        /// <param name="character"></param>
        /// <returns></returns>
        public static string[] SplitRemoveEmpty(this string data, string character)
        {
            return data.Split(new string[] { character }, StringSplitOptions.RemoveEmptyEntries);
        }
        #endregion

        #region To Stream

        public static MemoryStream ToStream(this string value)
        {
            MemoryStream ms = new MemoryStream();
            StreamWriter writer = new StreamWriter(ms);
            writer.Write(value);
            writer.Flush();
            return ms;
        }
        #endregion
    }
}
